#ifndef YIGCABLEGRAPHIC_H
#define YIGCABLEGRAPHIC_H

// System includes
#include <QObject>
#include <QGraphicsLineItem>
#include <QPen>
#include <QGraphicsScene>
#include <graphics/yigbasegraphic.h>

// Local includes

/**
*   YigCableGraphic
*   draws the cable segments between synth ellipses
*/
class YigCableGraphic : public YigBaseGraphic, public QGraphicsLineItem
{
    Q_OBJECT

public:

    /**
    *   @enum CableOutputType Declares the three types of output a cable could have
    *   @value NO_OUTPUT Cable has no output, for instance if it were a current cable from the mouse, might be phased out
    *   @value AUDIO This cable is connected to a synth's audio input
    *   @value MODULATION This cable is connected to a synth's mod input
    */
    enum CableOutputType {
        NO_OUTPUT,
        AUDIO,
        MODULATION
    };

    /**
    *   YigCableGraphic constructor
    *   @param const QLineF &line Initial line to create the graphic with
    *   @param QString inputKey the map key for the synth that BEGINS the cable
    *   @param QString outputKey the map key for the synth that ENDS the cable
    *   @param CableOutputType outputType the type of output for the cable, either NO_OUTPUT, AUDIO, or MODULATION
    */
    YigCableGraphic(const QLineF &line, QString inputKey, QString outputKey = "", CableOutputType outputType = NO_OUTPUT,
                    int audioInputIndex = 0, QGraphicsLineItem* parent = 0);

    ~YigCableGraphic();

    /**
    * addArrow() adds the output arrow from the scene
    */
    void addArrow();

    /**
    * removeArrow() removes the output arrow from the scene
    */
    void removeArrow();

    /**
    *   getIntputKey Get the map key for the synth that BEGINS the cable
    *   @return QString The map key
    */
    QString getInputKey();

    /**
    *   getOutputKey Get the map key for the synth that ENDS the cable
    *   @return QString The map key
    */
    QString getOutputKey();

    /**
    *   setOutputKey Sets the map key for the synth that ENDS the cable
    *   @param QString outputKey The map key
    */
    void setOutputKey(QString outputKey);

    /**
    *   getOutputType Get the type of output for the cable, either NO_OUTPUT, AUDIO, or MODULATION
    *   @return CableOutputType The type
    */
    CableOutputType getOutputType();

    /**
    *   getAudioInputIndex() returns the audio bus that inputs into this cables, used for drawing opengl cables
    *   return int the index
    */
    int getAudioInputIndex();

    /**
    *   setPoint1 the begin point for this line
    *   QPoint point the new point 1
    */
    void setPoint1(QPoint point);

    /**
    *   setPoint1 the end point for this line
    *   QPoint point the new point 2
    */
    void setPoint2(QPoint point);

    /**
    *   setOutputType Sets the type of output for the cable, either NO_OUTPUT, AUDIO, or MODULATION
    *   @param CableOutputType outputType The type
    */
    void setOutputType(CableOutputType outputType);

    /**
    *   updateCurrentPoint Updates the last point of the last line of the cable, because of mouse movement
    *   @param QPoint point The new point where the line will end
    */
    void updateCurrentPoint(QPoint point);

    /**
    *   update the position of this graphic, used to emit posChanged for networking
    *   @param QPointF& point the new position
    */
    void updatePos( const QPointF& point );

    /**
    *   itemClick When the user clicks on one of items
    *   @param QGraphicsItem* item
    */
    void itemClick(QGraphicsItem* item);

    /**
    *   addLineSegment Add a new line segment at the end of the current list of lines
    *   @param QPoint point the X/Y coordinate to where the new line will connect
    *   it will always go come the last point, if there is no other line, it will be a line to/from the same point
    *   @return QGraphicsLineItem* pointer to the new line graphic made
    */
    //QGraphicsLineItem* addLineSegment(QPoint point);

    /**
    *   removeFromScene Removes all line segments from the given scen
    *   @param QGraphicsScene* scene The scene from which we remove the lines
    */
    void removeFromScene(QGraphicsScene* scene);

    /** This is a bit of a hack...
    *   mouseClickEndPoint adjusts the last 2 lines to the point, to offset the new line creating by the mouse click in the view
    *   @param QPoint point The new end point of the cable
    */
    void mouseClickEndPoint(QPoint point);

    /**
    *   setSelectable Sets whether the cable is selectable/movable
    *   bool selectableBool
    */
    void setSelectable(bool sectableBool);

    /**
    *   keyboardDelete Called from a contained line when the local user attempts to delete it from their keyboard
    */
    void keyboardDelete();

    /**
    *   setMapKey
    *   @param QString mapKey stores the map key for this cable internally
    */
    void setMapKey(QString mapKey);

    /**
    *   getMapKey
    *   @return QString mapKey for this cable in the YigNetworkChannelView cableGraphicMap
    */
    QString getMapKey();

    /** overridden to change highlight painting */
    //void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

signals:

    void cableKeyboardDeleted(QString mapKey);

public slots:

private:

    /**
    * Check to see if the cable is too long, if so, disconnect it
    */
    void autoDisconnect();

    /**
    *   Redraw the arrow so it rotates with the cable angle
    */
    void redrawHalfArrow();


    float getAngleABC(QPointF a, QPointF b, QPointF c);

    static const int ARROW_SIZE = 50;

    /** Output direction line */
    //QGraphicsPolygonItem* outputTriangle;
    //QGraphicsLineItem* halfArrow;

    /** YigNetworkChannelView cable map key */
    QString mMapKey;
    /** map keys for the input and output synth */
    QString mInputKey, mOutputKey;
    /** string defining the type of output for the cable, either NO_OUTPUT, AUDIO, or MODULATION */
    CableOutputType mOutputType;
    /** List containing all of the lines that make up this cable */
    //QList<QGraphicsLineItem*> lineList;
    /** Draws the line */
    QPen pen;
    /** color of the arrow, modified during glow */
    QColor arrowColor;
    /** used to spread out autodisconnect calls */
    int autoCounter;
    /** audio index for the inputting signal on the scsynth server */
    int mAudioInputIndex;
};

#endif // YIGCABLEGRAPHIC_H
